Validate API-supplied paths to prevent directory traversal#398
Merged
Conversation
file.dest and file.filename values from the Nebula API were used directly in filesystem operations (directory creation, download target paths, decompression destinations) with no validation, allowing a compromised server or MITM to write files outside the mod library. Adds IsSubPath() to KnUtils using Path.GetFullPath containment to reject absolute paths and "../" traversal sequences. InstallMod and InstallBuild now validate both fields before use and cancel the task if either escapes the mod directory. Also adds belt-and-suspenders entry path validation to the SharpCompress extraction loops and fixes the WriteSymbolicLink lambda to reject symlink targets that resolve outside the destination directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shivansps
approved these changes
May 6, 2026
wookieejedi
reviewed
May 7, 2026
| } | ||
|
|
||
| Info = "Tasks: " + ProgressCurrent + "/" + ProgressBarMax; | ||
| if (!KnUtils.IsSubPath(modPath, file.filename)) |
Contributor
There was a problem hiding this comment.
Warning: file is not null here, possible null reference against arg for parameter candiatePath
wookieejedi
reviewed
May 7, 2026
| { | ||
| file.dest = string.Empty; | ||
| } | ||
| if (!KnUtils.IsSubPath(modPath, file.filename)) |
Contributor
There was a problem hiding this comment.
Warning: file is not null here, possible null reference against arg for parameter candiatePath
wookieejedi
reviewed
May 7, 2026
| { | ||
| Log.Add(Log.LogSeverity.Error, "TaskItemViewModel.InstallBuild()", $"Unsafe dest path in build '{build.id}': {file.dest}"); | ||
| CancelTaskCommand(); | ||
| return false; |
Contributor
There was a problem hiding this comment.
This return line needs to be removed, otherwise it does not build
Contributor
|
I've pushed changs to fix the above issues, and my tests work as expected |
Merged
Shivansps
pushed a commit
that referenced
this pull request
May 10, 2026
Removing `return false` in the second commit to #398 was the wrong fix; it should have been changed to `return null`. But this had an unexpected benefit as it turns out several other places in the code need proper handling of task cancellation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
file.dest and file.filename values from the Nebula API were used directly in filesystem operations (directory creation, download target paths, decompression destinations) with no validation, allowing a compromised server or MITM to write files outside the mod library.
Adds IsSubPath() to KnUtils using Path.GetFullPath containment to reject absolute paths and "../" traversal sequences. InstallMod and InstallBuild now validate both fields before use and cancel the task if either escapes the mod directory.
Also adds belt-and-suspenders entry path validation to the SharpCompress extraction loops and fixes the WriteSymbolicLink lambda to reject symlink targets that resolve outside the destination directory.